package org.jenijo.querydroid;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.UUID;

import org.jenijo.querydroid.model.QCM;
import org.jenijo.querydroid.model.Question;
import org.jenijo.querydroid.model.Reponse;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MainActivity extends Activity implements View.OnClickListener,
AdapterView.OnItemClickListener, OnClickListener {
	private static String				login;
	private static String				password;
	private static String				server;
	private static final int			QuestionRequest	= 1;
	private static final int			ResultRequest	= 2;
	private UUID						uuid;
	private TextView					qcmTitle, qcmDesc, qcmAuthor;
	private Button						startQcmBut, refreshQcmListBut;
	private ListView					qcmList;
	private QCMAdapter					adap;
	private ArrayList<QCM>				listItem;
	private ArrayList<Question>			questArray;
	private ProgressBar					pb;
	private AsyncTask<Void, Void, Void>	loadQuestionTask;
	private AsyncTask<Void, Void, Void>	loadQcmListTask;
	private int							target;
	private HashMap<Integer, Integer>	answersMap;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		setContentView(R.layout.main);
		
		ServerErrorHandler.ctx = this;
		
		uuid = new DeviceUuidFactory(this).getDeviceUuid();
		
		login = getIntent().getStringExtra("login");
		password = getIntent().getStringExtra("password");
		server = getIntent().getStringExtra("server");
		
		SharedPreferences pref = getSharedPreferences("QDServerList", 0);
		SharedPreferences.Editor prefEditor = pref.edit();
		String servList = pref.getString("ServerList", null);
		if(servList == null){
			prefEditor.putString("ServerList", server);
			prefEditor.commit();
		}else{
			if(!servList.contains(server)){
				servList += ";" + server;
				prefEditor.putString("ServerList", servList);
				prefEditor.commit();
			}
		}
		
		qcmTitle = (TextView) findViewById(R.id.tvQCMTitle);
		qcmDesc = (TextView) findViewById(R.id.tvQCMDesc);
		qcmAuthor = (TextView) findViewById(R.id.tvQCMAuthor);
		
		startQcmBut = (Button) findViewById(R.id.startQcmBut);
		refreshQcmListBut = (Button) findViewById(R.id.refreshQcmListBut);
		qcmList = (ListView) findViewById(R.id.QCMListView);
		pb = (ProgressBar) findViewById(R.id.qcmProgressBar);
		
		listItem = new ArrayList<QCM>();
		
		adap = new QCMAdapter(this, listItem);
		qcmList.setAdapter(adap);
		
		qcmList.setOnItemClickListener(this);
		
		if(this.isConnected())
			populateList();
		else{
			new AlertDialog.Builder(this).setTitle(R.string.error).setMessage(R.string.notConnectedError).setPositiveButton(R.string.okButton, null).show();
		}
		
		startQcmBut.setOnClickListener(this);
		refreshQcmListBut.setOnClickListener(this);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if(requestCode == QuestionRequest){
			if(resultCode == RESULT_OK){
				int num_rep = data.getIntExtra("num_rep", -1);
				int num_quest = data.getIntExtra("num_quest", -1);
				answersMap.put(num_quest, num_rep);
				
				if(num_quest < questArray.size()){
					Intent i = new Intent(MainActivity.this, QuestionActivity.class);
					i.putExtra("question", questArray.get(num_quest));
					i.putExtra("maxQuestions", questArray.size());
					startActivityForResult(i, QuestionRequest);
				}else{
					new AlertDialog.Builder(MainActivity.this).setTitle(R.string.testCompleteTitle).setMessage(R.string.testCompleteMessage).setNegativeButton(R.string.noButton, null).setPositiveButton(R.string.yesButton, this).show();
				}
			}else{
				// n'arrive jamais
			}
		}else if(requestCode == ResultRequest){
			if(resultCode == RESULT_OK){
				int qcm_id = data.getIntExtra("qcm_id", -1);
				Log.i("QD", String.valueOf(qcm_id));
				if(qcm_id > -1){
					for(QCM q : listItem){
						if(q.getId() == qcm_id){
							listItem.remove(q);
							break;
						}
					}
					adap.notifyDataSetChanged();
					populateList();
				}
			}else{
				// n'arrive jamais
			}
		}
	}
	
	private void populateList() {
		if(loadQcmListTask != null)
			loadQcmListTask.cancel(true);
		loadQcmListTask = new AsyncTask<Void, Void, Void>() {
			RestClient	client;
			
			@Override
			protected void onPreExecute() {
				super.onPreExecute();
				pb.setVisibility(View.VISIBLE);
				listItem.clear();
				adap.notifyDataSetChanged();
				client = new RestClient("http://" + server + "/android/qcm/list");
				client.addParam("login", login).addParam("password", password);
			}
			
			@Override
			protected Void doInBackground(Void... params) {
				try{
					client.execute(RequestMethod.POST);
				}catch (UnsupportedEncodingException e){
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return null;
			}
			
			@Override
			protected void onPostExecute(Void result) {
				super.onPostExecute(result);
				String type = "";
				if(client.getResponse() != null){
					try{
						JSONObject obj = new JSONObject(client.getResponse());
						type = obj.getString("type");
						
						if(type.equals("fetchSuccess")){
							JSONArray arr = obj.getJSONArray("content");
							for(int i = 0; i < arr.length(); i++){
								JSONObject jsonQcm = arr.getJSONObject(i);
								QCM qcm = new QCM(Integer.parseInt(jsonQcm.getString("qcm_id")), jsonQcm.getString("titre"), jsonQcm.getString("description"), StringUtil.ucfirst(jsonQcm.getString("prenom"))+" "+StringUtil.ucfirst(jsonQcm.getString("nom")));
								listItem.add(qcm);
							}
							adap.notifyDataSetChanged();
						}else if(type.equals("fetchError")){
							new AlertDialog.Builder(MainActivity.this).setTitle(R.string.error).setMessage(ServerErrorHandler.err(obj.getString("message"))).setPositiveButton(R.string.okButton, null).show();
						}else{
							new AlertDialog.Builder(MainActivity.this).setTitle(R.string.internalServerError).setMessage(client.getResponse()).setPositiveButton(R.string.okButton, null).show();
						}
					}catch (JSONException e){
						new AlertDialog.Builder(MainActivity.this).setTitle(R.string.error).setMessage(e.getLocalizedMessage()+"\n\n"+client.getResponse()).setPositiveButton(R.string.okButton, null).show();
					}
				}else
					new AlertDialog.Builder(MainActivity.this).setTitle(R.string.error).setMessage(client.getErrorMessage()).setPositiveButton(R.string.okButton, null).show();
				pb.setVisibility(View.INVISIBLE);
			}
		}.execute();
	}
	
	public void onClick(View arg0) {
		switch(arg0.getId()) {
			case R.id.refreshQcmListBut:
				if(this.isConnected())
					populateList();
				else{
					new AlertDialog.Builder(this).setTitle(R.string.error).setMessage(R.string.notConnectedError).setPositiveButton(R.string.okButton, null).show();
				}
				break;
			case R.id.startQcmBut:
				if(this.isConnected()){
					qcmTitle.setVisibility(View.INVISIBLE);
					qcmAuthor.setVisibility(View.INVISIBLE);
					qcmDesc.setVisibility(View.INVISIBLE);
					startQcmBut.setEnabled(false);
					loadQuestions();
				}else{
					new AlertDialog.Builder(this).setTitle(R.string.error).setMessage(R.string.notConnectedError).setPositiveButton(R.string.okButton, null).show();
				}
				break;
			default:
				break;
		}
		
	}
	
	private void loadQuestions() {
		if(loadQuestionTask != null)
			loadQuestionTask.cancel(true);
		loadQuestionTask = new AsyncTask<Void, Void, Void>() {
			RestClient	client;
			
			@Override
			protected void onPreExecute() {
				super.onPreExecute();
				pb.setVisibility(View.VISIBLE);
				client = new RestClient("http://" + server + "/android/qcm/get");
				client.addParam("login", login).addParam("password", password).addParam("qcm", String.valueOf(target)).addParam("device_uuid", uuid.toString());
			}
			
			@Override
			protected Void doInBackground(Void... params) {
				try{
					client.execute(RequestMethod.POST);
				}catch (UnsupportedEncodingException e){
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return null;
			}
			
			@Override
			protected void onPostExecute(Void result) {
				super.onPostExecute(result);
				String type;
				if(client.getResponse() != null){
					try{
						JSONObject obj = new JSONObject(client.getResponse());
						type = obj.getString("type");
						
						if(type.equals("fetchSuccess")){
							questArray = new ArrayList<Question>();
							answersMap = new HashMap<Integer, Integer>();
							JSONArray arr = obj.getJSONArray("content");
							for(int i = 0; i < arr.length(); i++){
								JSONObject jsonQuest = arr.getJSONObject(i);
								Question q = new Question(jsonQuest.getInt("num_quest"), jsonQuest.getString("enonce"));
								JSONArray repArr = jsonQuest.getJSONArray("reponses");
								for(int j = 0; j < repArr.length(); j++){
									JSONObject jsonRep = repArr.getJSONObject(j);
									Reponse r = new Reponse(jsonRep.getInt("num_rep"), jsonRep.getString("texte"));
									q.addReponse(r);
								}
								questArray.add(q);
							}
							Intent i = new Intent(MainActivity.this, QuestionActivity.class);
							i.putExtra("question", questArray.get(0));
							i.putExtra("maxQuestions", questArray.size());
							startActivityForResult(i, QuestionRequest);
							
						}else if(type.equals("fetchError")){
							new AlertDialog.Builder(MainActivity.this).setTitle(R.string.error).setMessage(ServerErrorHandler.err(obj.getString("message"))).setPositiveButton(R.string.okButton, null).show();
						}else{
							new AlertDialog.Builder(MainActivity.this).setTitle(R.string.internalServerError).setMessage(client.getResponse()).setPositiveButton(R.string.okButton, null).show();
						}
					}catch (JSONException e){
						new AlertDialog.Builder(MainActivity.this).setTitle(R.string.error).setMessage(e.getLocalizedMessage()
						                                                                               + "\n" + client.getResponse()).setPositiveButton(R.string.okButton, null).show();
					}catch (IndexOutOfBoundsException e){
						new AlertDialog.Builder(MainActivity.this).setTitle(R.string.error).setMessage(R.string.emptyTestError).setPositiveButton(R.string.okButton, null).show();
					}
				}else
					new AlertDialog.Builder(MainActivity.this).setTitle(R.string.error).setMessage(client.getErrorMessage()).setPositiveButton(R.string.okButton, null).show();
				pb.setVisibility(View.INVISIBLE);
			}
		}.execute();
	}
	
	public void onItemClick(AdapterView<?> av, View v, int position, long id) {
		QCM qcm = (QCM) qcmList.getItemAtPosition(position);
		qcmTitle.setText(qcm.getTitre());
		qcmTitle.setVisibility(View.VISIBLE);
		qcmAuthor.setText(getString(R.string.by)+" "+qcm.getAuthor());
		qcmAuthor.setVisibility(View.VISIBLE);
		qcmDesc.setText(qcm.getDescription());
		qcmDesc.setVisibility(View.VISIBLE);
		startQcmBut.setEnabled(true);
		target = qcm.getId();
	}
	
	private boolean isConnected() {
		ConnectivityManager connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo networkInfo = null;
		if(connectivityManager != null){
			networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
			if(networkInfo == null){
				networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
			}
		}
		if(networkInfo == null)
			return false;
		else
			return networkInfo.isConnected();
	}
	
	public void onClick(DialogInterface arg0, int arg1) {
		Intent i = new Intent(this, ResultsActivity.class);
		i.putExtra("qcm_id", target);
		i.putExtra("answers", answersMap);
		i.putExtra("server", server);
		i.putExtra("login", login);
		i.putExtra("password", password);
		startActivityForResult(i, ResultRequest);
		
	}
}
